package lib.self.fresco.provider;

import android.content.Context;
import android.net.Uri;
import android.widget.ImageView;

import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.backends.pipeline.PipelineDraweeControllerBuilder;
import com.facebook.drawee.controller.AbstractDraweeController;
import com.facebook.drawee.controller.BaseControllerListener;
import com.facebook.drawee.controller.ControllerListener;
import com.facebook.drawee.drawable.ScalingUtils.ScaleType;
import com.facebook.drawee.generic.RoundingParams;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.SimpleDraweeView;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.facebook.imagepipeline.image.ImageInfo;
import com.facebook.imagepipeline.postprocessors.IterativeBoxBlurPostProcessor;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;

import lib.self.ConstEx;
import lib.self.fresco.NetworkImageListener;
import lib.self.fresco.renderer.BaseRenderer;
import lib.self.fresco.renderer.BlurRenderer;
import lib.self.fresco.renderer.CircleRenderer;
import lib.self.fresco.renderer.CornerRenderer;


/**
 * description: Fresco专用
 * author: Steven Xiao
 * date: 2017/4/27
 */
public class FrescoProvider extends BaseProvider {
    private ControllerListener mControllerListener;
    private PipelineDraweeControllerBuilder mBuilder;
    private SimpleDraweeView mSimpleDraweeView;
    private boolean mSetPlacehoder;

    public FrescoProvider(Context mContext, ImageView iv) {
        super(mContext, iv);
        mBuilder = Fresco.newDraweeControllerBuilder();
        mSimpleDraweeView = (SimpleDraweeView) iv;
        mSimpleDraweeView.getHierarchy().setActualImageScaleType(ScaleType.CENTER_CROP);
    }

    @Override
    public void load(String url, int placeHolderRid, BaseRenderer renderer, int fadeDuration) {
        if (placeHolderRid != 0) {
            if (!mSetPlacehoder) {
                mSimpleDraweeView.getHierarchy().setPlaceholderImage(placeHolderRid);
                mSetPlacehoder = true;
            }
        }

        if (fadeDuration != ConstEx.KInvalidValue) {
            mSimpleDraweeView.getHierarchy().setFadeDuration(fadeDuration);
        }

        if (renderer != null) {
            if (renderer instanceof CircleRenderer) {
                RoundingParams rp = mSimpleDraweeView.getHierarchy().getRoundingParams();
                if (rp == null) {
                    rp = RoundingParams.asCircle();
                } else {
                    rp.setRoundAsCircle(true);
                }
                mSimpleDraweeView.getHierarchy().setRoundingParams(rp);
            } else if (renderer instanceof CornerRenderer) {
                CornerRenderer r = (CornerRenderer) renderer;
                RoundingParams rp = mSimpleDraweeView.getHierarchy().getRoundingParams();
                if (rp == null) {
                    rp = RoundingParams.fromCornersRadius(r.getRadius());
                } else {
                    rp.setCornersRadius(r.getRadius());
                }
                mSimpleDraweeView.getHierarchy().setRoundingParams(rp);
            } else if (renderer instanceof BlurRenderer) {
                BlurRenderer r = (BlurRenderer) renderer;
                IterativeBoxBlurPostProcessor processor = new IterativeBoxBlurPostProcessor(r.getIterations(), r.getBlueRadius());
                if (r.isCircle()) {
                    RoundingParams rp = mSimpleDraweeView.getHierarchy().getRoundingParams();
                    if (rp == null) {
                        rp = RoundingParams.asCircle();
                    } else {
                        rp.setRoundAsCircle(true);
                    }
                    mSimpleDraweeView.getHierarchy().setRoundingParams(rp);
                }
                if (r.getCornerRadius() > 0) {
                    RoundingParams rp = mSimpleDraweeView.getHierarchy().getRoundingParams();
                    if (rp == null) {
                        rp = RoundingParams.fromCornersRadius(r.getCornerRadius());
                    } else {
                        rp.setCornersRadius(r.getCornerRadius());
                    }
                    mSimpleDraweeView.getHierarchy().setRoundingParams(rp);
                }
                try {
                    Uri uri = Uri.parse(url);
                    ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                            .setPostprocessor(processor)
                            .build();
                    AbstractDraweeController controller = Fresco.newDraweeControllerBuilder()
                            .setOldController(mSimpleDraweeView.getController())
                            .setImageRequest(request)
                            .build();
                    mSimpleDraweeView.setController(controller);
                    return;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        setImageURI(url);
    }

    @Override
    public void setListener(NetworkImageListener listener) {
        super.setListener(listener);
        if (listener == null) {
            return;
        }

        if (mControllerListener == null) {
            mControllerListener = new BaseControllerListener<ImageInfo>() {
                @Override
                public void onIntermediateImageSet(String id, final ImageInfo imageInfo) {
                    lib.self.fresco.ImageInfo info = new lib.self.fresco.ImageInfo() {
                        @Override
                        public int getWidth() {
                            return imageInfo.getWidth();
                        }

                        @Override
                        public int getHeight() {
                            return imageInfo.getHeight();
                        }
                    };
                    mListener.onImageSet(info);
                }

                @Override
                public void onFailure(String id, Throwable throwable) {
                    if (mSimpleDraweeView != null && mListener != null) {
                        mListener.onFailure();
                    }
                }
            };
        }
    }

    private void setImageURI(String uriString) {
        DraweeController controller = mBuilder
                .setOldController(mSimpleDraweeView.getController())
                .setControllerListener(mControllerListener)
                .setUri(uriString)
                .build();
        mSimpleDraweeView.setController(controller);
    }

    /**
     * 从缓存中清除指定的url
     *
     * @param url
     */
    @Override
    public void clearFromCache(String url) {
        ImagePipeline imagePipeline = Fresco.getImagePipeline();
        Uri uri = Uri.parse(url);
        imagePipeline.evictFromCache(uri);
    }
}
